<?php

namespace JsonLowCode;

use JsonSerializable;

class Theme implements JsonSerializable
{
    /**
     * 主题模式 是否黑暗模式
     * @var bool
     */
    protected bool $darkMode = false;

    /**
     * 是否跟随系统颜色
     * @var bool
     */
    protected bool $followSystemTheme = true;

    /**
     * 布局信息
     * @var array
     */
    protected array $layout = [
        'minWidth'=>900,
        'mode'=>'vertical-mix',
        'modeList'=>[
            [
                "value"=>"vertical",
                "label"=>"左侧菜单模式"
            ],
            [
                "value"=>"vertical-mix",
                "label"=>"左侧菜单混合模式"
            ],
            [
                "value"=>"horizontal",
                "label"=>"顶部菜单模式"
            ],
            [
                "value"=>"horizontal-mix",
                "label"=>"顶部菜单混合模式"
            ]
        ]
    ];

    /**
     * 主题颜色
     * @var string
     */
    protected string $scrollMode = "content";

    /**
     * 滚动模式列表
     * @var array|array[]
     */
    protected array $scrollModeList = [
        ["value"=> "wrapper","label"=> "外层滚动"],
        ["value"=> "content","label"=>"主体滚动"]
    ];

    /**
     * 主题颜色
     * @var string
     */
    protected string $themeColor = "#1890ff";

    /**
     * 主题颜色列表
     * @var array|string[]
     */
    protected array $themeColorList = [
        "#1890ff","#409EFF","#2d8cf0","#007AFF","#5ac8fa",
        "#5856D6","#536dfe","#9c27b0","#AF52DE","#0096c7",
        "#00C1D4","#34C759","#43a047","#7cb342","#c0ca33",
        "#78DEC7","#e53935","#d81b60","#f4511e","#fb8c00",
        "#ffb300","#fdd835","#6d4c41","#546e7a"
    ];

    protected array $otherColor = [
        "info"=>"#096dd9",
        "success"=>"#52c41a",
        "warning"=>"#faad14",
        "error"=>"#f5222d"
    ];

    /**
     * 是否自定义info颜色
     * @var bool
     */
    protected bool $isCustomizeInfoColor = false;

    /**
     * 是否固定header与tab
     * @var bool
     */
    protected bool $fixedHeaderAndTab = true;

    /**
     * 是否显示刷新按钮
     * @var bool
     */
    protected bool $showReload = true;

    /**
     * header 头部配置
     * @var array
     */
    protected array $header = [
        "inverted"=> false,
        "height"=> 56,
        "crumb"=> [
            "visible"=> true,
            "showIcon"=> true
        ]
    ];

    /**
     * 标签配置
     * @var array
     */
    protected array $tab = [
        "visible"=> true,
        "height"=> 44,
        "mode"=> "chrome",
        "modeList"=>[
            [
                "value"=> "chrome",
                "label"=> "谷歌风格"
            ],
            [
                "value"=> "button",
                "label"=> "按钮风格"
            ]
        ],
        "isCache"=> true
    ];

    /**
     * 侧边栏信息
     * @var array
     */
    protected array $sider = [
        "inverted"=> true,
        "width"=> 220,
        "collapsedWidth"=> 64,
        "mixWidth"=> 80,
        "mixCollapsedWidth"=> 48,
        "mixChildMenuWidth"=> 200
    ];

    /**
     * 菜单信息
     * @var array
     */
    protected array $menu = [
        "horizontalPosition"=> "flex-start",
        "horizontalPositionList"=> [
            [
                "value"=> "flex-start",
                "label"=> "居左"
            ],
            [
                "value"=> "center",
                "label"=> "居中"
            ],
            [
                "value"=> "flex-end",
                "label"=> "居右"
            ],
        ]
    ];

    /**
     * 底部信息
     * @var array
     */
    protected array $footer = [
        "fixed"=> false,
        "height"=> 48,
        "visible"=> true,
        "right"=> true,
        "inverted"=> false,
    ];

    /**
     * 页面信息
     * @var array
     */
    protected array $page = [
        "animate"=> true,
        "animateMode"=> "fade-slide",
        "animateModeList"=> [
            [
                "value"=> "fade-slide",
                "label"=> "滑动"
            ],
            [
                "value"=> "fade",
                "label"=> "消退"
            ],
            [
                "value"=> "fade-bottom",
                "label"=> "底部消退"
            ],
            [
                "value"=> "fade-scale",
                "label"=> "缩放消退"
            ],
            [
                "value"=> "zoom-fade",
                "label"=> "渐变"
            ],
            [
                "value"=> "zoom-out",
                "label"=> "闪现"
            ]
        ]
    ];

    /**
     * @var Theme|null
     */
    private static ?Theme $instance = null;


    /**
     * @param callable|null $callback
     */
    public function __construct(callable $callback = null)
    {
        if ($callback!=null){
            call_user_func($callback,$this);
        }
    }

    /**
     * @return $this
     */
    public static function instance(callable $callback = null): static
    {
        if (!self::$instance instanceof self) {
            self::$instance = new static($callback);
        }
        return self::$instance;
    }

    /**
     * 设置主题黑暗模式
     * @param bool $bool true=是,false=否
     * @return $this
     */
    public function darkMode(bool $bool = true): static
    {
        $this->darkMode = $bool;
        return $this;
    }

    /**
     * 设置是否跟随系统主题颜色
     * @param bool $bool true=是,false=否
     * @return $this
     */
    public function followSystemTheme(bool $bool = true): static
    {
        $this->followSystemTheme = $bool;
        return $this;
    }

    /**
     * 设置主体布局模式
     * @param string $mode  vertical-mix|vertical-mix|horizontal|horizontal-mix
     * @return $this
     */
    public function layout(string $mode = "vertical-mix"|"vertical-mix"|"horizontal"|"horizontal-mix"): static
    {
        $this->layout['mode'] = $mode;
        return $this;
    }

    /**
     * 设置滚动模式
     * @param string $mode "content" | "wrapper"
     * @return $this
     */
    public function scrollMode(string $mode = "content" | "wrapper"): static
    {
        $this->scrollMode = $mode;
        return $this;
    }


    /**
     * 设置主题激活状态主颜色
     * @param string $color
     * @return $this
     */
    public function themeColor(string $color): static
    {
        $this->themeColor = $color;
        return $this;
    }

    /**
     * 添加主题颜色
     * @param string $color
     * @return $this
     */
    public function addThemeColor(string $color): static
    {
        if (!in_array($color, $this->themeColorList)){
            $this->themeColorList[] = $color;
        }
        return $this;
    }

    /**
     * 删除主题颜色
     * @param string $color
     * @return $this
     */
    public function delThemeColor(string $color): static
    {
        $key = array_search($color,$this->themeColorList, true);
        if ($key!==false){
            unset($this->themeColorList[$key]);
        }
        return $this;
    }

    /**
     * 设置info类型颜色
     * @param string $color
     * @return $this
     */
    public function setInfoColor(string $color): static
    {
        $this->otherColor['info'] = $color;
        return $this;
    }

    /**
     * 设置success类型颜色
     * @param string $color
     * @return $this
     */
    public function setSuccessColor(string $color): static
    {
        $this->otherColor['success'] = $color;
        return $this;
    }

    /**
     * 设置error类型颜色
     * @param string $color
     * @return $this
     */
    public function setErrorColor(string $color): static
    {
        $this->otherColor['error'] = $color;
        return $this;
    }

    /**
     * 设置warning类型颜色
     * @param string $color
     * @return $this
     */
    public function setWarningColor(string $color): static
    {
        $this->otherColor['warning'] = $color;
        return $this;
    }

    /**
     * 是否固定header与tab
     * @param bool $bool true=是,false=否
     * @return $this
     */
    public function fixedHeaderAndTab(bool $bool = true): static
    {
        $this->fixedHeaderAndTab = $bool;
        return $this;
    }

    /**
     * 是否显示刷新按钮
     * @param bool $bool true=是,false=否
     * @return $this
     */
    public function showReload(bool $bool = true): static
    {
        $this->showReload = $bool;
        return $this;
    }

    /**
     * 设置header头部反转颜色
     * @param bool $bool
     * @return $this
     */
    public function setHeaderInverted(bool $bool = true): static
    {
        $this->header['inverted'] = $bool;
        return $this;
    }

    /**
     * 设置header头部高度
     * @param int $height
     * @return $this
     */
    public function setHeaderHeight(int $height = 56): static
    {
        $this->header['height'] = $height;
        return $this;
    }

    /**
     * 设置header头部面包屑
     * @param bool $visible
     * @param bool $showIcon
     * @return $this
     */
    public function setHeaderCrumb(bool $visible = true, bool $showIcon = true): static
    {
        $this->header['crumb'] = [
            "visible"=> $visible,
            "showIcon"=> $showIcon
        ];
        return $this;
    }

    /**
     * 设置tab 是否显示
     * @param bool $visible
     * @return $this
     */
    public function setTabVisible(bool $visible = true): static
    {
        $this->tab['visible'] = $visible;
        return $this;
    }

    /**
     * 设置tab 是否显示
     * @param int $height
     * @return $this
     */
    public function setTabHeight(int $height = 44): static
    {
        $this->tab['height'] = $height;
        return $this;
    }

    /**
     * 设置tab风格 谷歌或者按钮
     * @param string $mode chrome | button
     * @return $this
     */
    public function setTabMode(string $mode = "chrome" | "button"): static
    {
        $this->tab['mode'] = $mode;
        return $this;
    }

    /**
     * 设置tab 是否缓存tab标签
     * @param bool $bool
     * @return $this
     */
    public function setTabIsCache(bool $bool = true): static
    {
        $this->tab['isCache'] = $bool;
        return $this;
    }


    /**
     * 设置sider侧边栏反转颜色
     * @param bool $bool
     * @return $this
     */
    public function setSiderInverted(bool $bool = true): static
    {
        $this->sider['inverted'] = $bool;
        return $this;
    }

    /**
     * 设置sider侧边栏宽度与折叠宽度
     * @param int $width
     * @param int $mixWidth
     * @return $this
     */
    public function setSiderWidth(int $width = 220, int $mixWidth = 80): static
    {
        $this->sider['width'] = $width;
        $this->sider['mixWidth'] = $mixWidth;
        return $this;
    }

    /**
     * 设置sider侧边栏折叠宽度
     * @param int $collapsedWidth
     * @param int $mixCollapsedWidth
     * @return $this
     */
    public function setCollapsedWidth(int $collapsedWidth = 64, int $mixCollapsedWidth = 48): static
    {
        $this->sider['collapsedWidth'] = $collapsedWidth;
        $this->sider['mixCollapsedWidth'] = $mixCollapsedWidth;
        return $this;
    }

    /**
     * 设置sider侧边栏子菜单宽度
     * @param int $mixChildMenuWidth
     * @return $this
     */
    public function setMixChildMenuWidth(int $mixChildMenuWidth = 200): static
    {
        $this->sider['mixChildMenuWidth'] = $mixChildMenuWidth;
        return $this;
    }

    /**
     * 设置头部菜单位置
     * @param string $horizontalPosition flex-start|center|flex-end
     * @return $this
     */
    public function setMenuHorizontalPosition(string $horizontalPosition = "flex-start"|"center"|"flex-end"): static
    {
        $this->menu['horizontalPosition'] = $horizontalPosition;
        return $this;
    }

    /**
     * 设置footer是否固定底部
     * @param bool $bool
     * @return $this
     */
    public function setFooterFixed(bool $bool = true): static
    {
        $this->footer['fixed'] = $bool;
        return $this;
    }

    /**
     * 设置footer高度
     * @param int $height
     * @return $this
     */
    public function setFooterHeight(int $height = 48): static
    {
        $this->footer['height'] = $height;
        return $this;
    }

    /**
     * 设置底部是否居右
     * @param bool $bool
     * @return $this
     */
    public function setFooterRight(bool $bool = true): static
    {
        $this->footer['right'] = $bool;
        return $this;
    }

    /**
     * 设置底部是否反转颜色
     * @param bool $bool
     * @return $this
     */
    public function setFooterInverted(bool $bool = true): static
    {
        $this->footer['inverted'] = $bool;
        return $this;
    }

    /**
     * 设置页面是否启用动画效果
     * @param bool $bool
     * @return $this
     */
    public function setPageAnimate(bool $bool = true): static
    {
        $this->page['animate'] = $bool;
        return $this;
    }

    /**
     * 设置页面切换动画
     * @param string $animateMode fade-slide|fade|fade-bottom|fade-scale|zoom-fade|zoom-out
     * @return $this
     */
    public function setPageAnimateMode(string $animateMode = "fade-slide"|"fade"|"fade-bottom"|"fade-scale"|"zoom-fade"|"zoom-out"): static
    {
        $this->page['animateMode'] = $animateMode;
        return $this;
    }

    public function toArray(){
        return [
          'darkMode'=>$this->darkMode,
          'followSystemTheme'=>$this->followSystemTheme,
          'layout'=>$this->layout,
          'scrollMode'=>$this->scrollMode,
          'scrollModeList'=>$this->scrollModeList,
          'themeColor'=>$this->themeColor,
          'themeColorList'=>$this->themeColorList,
          'otherColor'=>$this->otherColor,
          'isCustomizeInfoColor'=>$this->isCustomizeInfoColor,
          'fixedHeaderAndTab'=>$this->fixedHeaderAndTab,
          'showReload'=>$this->showReload,
          'header'=>$this->header,
          'tab'=>$this->tab,
          'sider'=>$this->sider,
          'menu'=>$this->menu,
          'footer'=>$this->footer,
          'page'=>$this->page,
        ];
    }


    public function jsonSerialize()
    {
        return $this->toArray();
    }
}
